/*
 * LDIR
 *
 * LDIR, a GPS cartography application built for Let's Do It Romania eco
 * campaign.
 * Copyright (C) 2010 Genera Software <office@generasoftware.com>
 *
 * http://generasoftware.com/
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 * Place, Suite 330, Boston, MA 02111-1307 USA
 */
#include <utf.h>
#include "WsObject.h"
#include "FieldsStringTable.h"
#include "Logger.h"

////////////////////////////////////////////////////////////////////////////////
CWsObject::CWsObject()
	{
	iOwnsEntity = ETrue;
	}

////////////////////////////////////////////////////////////////////////////////
CWsObject::CWsObject( CEntity* aEntity, TBool aOwnsEntity ) :
	iEntity( aEntity ), iOwnsEntity( aOwnsEntity )
	{

	}

////////////////////////////////////////////////////////////////////////////////
CWsObject::~CWsObject()
	{
	if ( iOwnsEntity )
		{
		delete iEntity;
		}
	delete iBuffer;
	}

////////////////////////////////////////////////////////////////////////////////
CWsObject* CWsObject::NewLC()
	{
	CWsObject* self = new ( ELeave ) CWsObject();
	CleanupStack::PushL( self );
	self->ConstructL();
	return self;
	}

////////////////////////////////////////////////////////////////////////////////
CWsObject* CWsObject::NewLC( CEntity* aEntity, TBool aOwnsEntity )
	{
	CWsObject* self = new ( ELeave ) CWsObject( aEntity, aOwnsEntity );
	CleanupStack::PushL( self );
	self->ConstructL();
	return self;
	}

////////////////////////////////////////////////////////////////////////////////
CWsObject* CWsObject::NewL()
	{
	CWsObject* self = CWsObject::NewLC();
	CleanupStack::Pop(); // self;
	return self;
	}

////////////////////////////////////////////////////////////////////////////////
CWsObject* CWsObject::NewL( CEntity* aEntity, TBool aOwnsEntity )
	{
	CWsObject* self = CWsObject::NewLC( aEntity, aOwnsEntity );
	CleanupStack::Pop(); // self;
	return self;
	}

////////////////////////////////////////////////////////////////////////////////
void CWsObject::ConstructL()
	{
	if ( !iEntity )
		{
		iEntity = CEntity::NewL( obj_type );
		}
	}

////////////////////////////////////////////////////////////////////////////////
HBufC8* CWsObject::EncodeL( CJsonGenerator& aJsonGenerator )
	{
	HBufC8* buffer = NULL;
	aJsonGenerator.SetRoot( iEntity );
	TInt retValue = aJsonGenerator.GenerateL( buffer );
	return buffer;
	}

////////////////////////////////////////////////////////////////////////////////
void CWsObject::DecodeL( const TDesC8& aDesC, CJsonParser& aJsonParser )
	{
	if ( iOwnsEntity )
		{
		delete iEntity;
		iEntity = NULL;
		}
	aJsonParser.PrepareParser();
	TInt retValue = aJsonParser.ParseL( aDesC );
	iEntity = aJsonParser.GetDOM();
	}

//////////////////////////////////////////////////////////////////////////
CEntity* CWsObject::GetEntity( const TInt aAttrNameIndex )
	{
	return iEntity->GetEntity( aAttrNameIndex );
	}

////////////////////////////////////////////////////////////////////////////////
TInt CWsObject::GetIntAttribute( const TInt aAttrNameIndex, TInt& aValue )
	{
	aValue = 0;
	CEntity* entity = GetEntity( aAttrNameIndex );
	if ( entity && entity->Type() == int_type )
		{
		aValue = entity->GetInt();
		return KErrNone;
		}
	else
		return KErrNotFound;
	}

////////////////////////////////////////////////////////////////////////////////
TInt CWsObject::GetRealAttribute( const TInt aAttrNameIndex, TReal& aValue )
	{
	aValue = 0;
	CEntity* entity = GetEntity( aAttrNameIndex );
	if ( entity && entity->Type() == real_type )
		{
		aValue = entity->GetReal();
		return KErrNone;
		}
	else
		return KErrNotFound;
	}

////////////////////////////////////////////////////////////////////////////////
TBool CWsObject::BoolAttribute( const TInt aAttrNameIndex )
	{
	CEntity* entity = GetEntity( aAttrNameIndex );
	if ( entity && entity->Type() == bool_type )
		return entity->GetBool();

	return EFalse;
	}

////////////////////////////////////////////////////////////////////////////////
const TDesC& CWsObject::GetDesAttribute( const TInt aAttrNameIndex )
	{
	CEntity* entity = GetEntity( aAttrNameIndex );
	if ( entity && entity->Type() == str_type )
		{
		delete iBuffer;
		iBuffer = CnvUtfConverter::ConvertToUnicodeFromUtf8L( entity->GetStr() );
		return *iBuffer;
		}

	return KNullDesC;
	}

////////////////////////////////////////////////////////////////////////////////
const TDesC8& CWsObject::GetDes8Attribute( const TInt aAttrNameIndex )
	{
	CEntity* entity = GetEntity( aAttrNameIndex );
	if ( entity && entity->Type() == str_type )
		{
		return entity->GetStr();
		}

	return KNullDesC8;
	}

////////////////////////////////////////////////////////////////////////////////
MWsObject* CWsObject::GetWsObjectL( const TInt aAttrNameIndex )
	{
	CEntity* entity = GetEntity( aAttrNameIndex );
	CWsObject* wsObject = NULL;
	if ( entity )
		{
		wsObject = CWsObject::NewL( entity, EFalse );
		}
	return wsObject;
	}

void CWsObject::AddBoolAttributeL( const TInt aAttrNameIndex,
	const TBool aValue )
	{
	iEntity->DeleteEntity( aAttrNameIndex );
	CEntity* child = CEntity::NewLC( pair_type );
	CEntity* pairValue = CEntity::NewLC( bool_type );
	pairValue->SetValueL( ( bool ) aValue );
	CPair* pair = CPair::NewL( aAttrNameIndex, pairValue );
	CleanupStack::Pop( pairValue );
	CleanupStack::PushL( pair );
	child->SetValueL( pair );
	CleanupStack::Pop( pair );
	iEntity->AddChildL( child );
	CleanupStack::Pop( child );
	}

void CWsObject::AddIntAttributeL( const TInt aAttrNameIndex, const TInt aValue )
	{
	iEntity->DeleteEntity( aAttrNameIndex );
	CEntity* child = CEntity::NewLC( pair_type );
	CEntity* pairValue = CEntity::NewLC( int_type );
	pairValue->SetValueL( aValue );
	CPair* pair = CPair::NewL( aAttrNameIndex, pairValue );
	CleanupStack::Pop( pairValue );
	CleanupStack::PushL( pair );
	child->SetValueL( pair );
	CleanupStack::Pop( pair );
	iEntity->AddChildL( child );
	CleanupStack::Pop( child );
	}

void CWsObject::AddRealAttributeL( const TInt aAttrNameIndex,
	const TReal aValue )
	{
	iEntity->DeleteEntity( aAttrNameIndex );
	CEntity* child = CEntity::NewLC( pair_type );
	CEntity* pairValue = CEntity::NewLC( real_type );
	pairValue->SetValueL( aValue );
	CPair* pair = CPair::NewL( aAttrNameIndex, pairValue );
	CleanupStack::Pop( pairValue );
	CleanupStack::PushL( pair );
	child->SetValueL( pair );
	CleanupStack::Pop( pair );
	iEntity->AddChildL( child );
	CleanupStack::Pop( child );
	}

void CWsObject::AddDesAttributeL( const TInt aAttrNameIndex,
	const TDesC& aValue )
	{
	iEntity->DeleteEntity( aAttrNameIndex );
	CEntity* child = CEntity::NewLC( pair_type );
	CEntity* pairValue = CEntity::NewLC( str_type );
	HBufC8* tmp = CnvUtfConverter::ConvertFromUnicodeToUtf8L( aValue );
	CleanupStack::PushL( tmp );
	pairValue->SetValueL( *tmp );
	CleanupStack::PopAndDestroy( tmp );
	CPair* pair = CPair::NewL( aAttrNameIndex, pairValue );
	CleanupStack::Pop( pairValue );
	CleanupStack::PushL( pair );
	child->SetValueL( pair );
	CleanupStack::Pop( pair );
	iEntity->AddChildL( child );
	CleanupStack::Pop( child );
	}
void CWsObject::AddDes8AttributeL( const TInt aAttrNameIndex,
	const TDesC8& aValue )
	{
	iEntity->DeleteEntity( aAttrNameIndex );
	CEntity* child = CEntity::NewLC( pair_type );
	CEntity* pairValue = CEntity::NewLC( str_type );
	pairValue->SetValueL( aValue );
	CPair* pair = CPair::NewL( aAttrNameIndex, pairValue );
	CleanupStack::Pop( pairValue );
	CleanupStack::PushL( pair );
	child->SetValueL( pair );
	CleanupStack::Pop( pair );
	iEntity->AddChildL( child );
	CleanupStack::Pop( child );
	}

////////////////////////////////////////////////////////////////////////////////
// clones entity
void CWsObject::AddEntityL( const TInt aAttrNameIndex, const CEntity& aEntity )
	{
	iEntity->DeleteEntity( aAttrNameIndex );
	CEntity* child = CEntity::NewLC( pair_type );
	CPair* pair = CPair::NewL( aAttrNameIndex, aEntity.CloneL() );
	CleanupStack::PushL( pair );
	child->SetValueL( pair );
	CleanupStack::Pop( pair );
	iEntity->AddChildL( child );
	CleanupStack::Pop( child );
	}

void CWsObject::AppendEntityL( const CEntity& aEntity )
	{
	__ASSERT_ALWAYS( iEntity, User::Invariant());
	__ASSERT_ALWAYS(array_type == iEntity->Type(), User::Invariant());
	iEntity->AddChildL( aEntity.CloneL() );
	}

////////////////////////////////////////////////////////////////////////////////
CEntity* CWsObject::Entity()
	{
	return iEntity;
	}

////////////////////////////////////////////////////////////////////////////////
void CWsObject::ReadStreamDescL( const RReadStream& aReadStream, HBufC8*& aDesc )
	{

	}

void CWsObject::WriteStreamDescL( RWriteStream& aWriteStream,
	const TDesC8& aDesc ) const
	{

	}

// ENd of file
